<?php
	require_once("config.php");

class Data
{
	private $link;
	private $_list;
	private $_types;
	
	public function __construct($con)
	{
		$this->link = $con;
	}
	
	private function mysql_fix_string($string)
	{
		if (get_magic_quotes_gpc())
			$string = stripslashes($string);
		return mysql_real_escape_string($string);
	}
	
	private function mysql_entities_fix_string($string)
	{
		return htmlentities($this->mysql_entities_fix_string($string));
	}
	
	private function sql_get_select_stmt($args)
	{
		$keywords = preg_split("/[\s,]+/",$args[0]);
		$count = count($keywords);
		$types = ""; //string of param types
		$typeCount = 0;
		$sql = $args[0]; //sanitized result string
		$isSelect = false;
		$selectList = null;
		for ($i=0; $i < $count; $i++) {
			$keyword = $keywords[$i];
			if ($keyword == "=" || $keyword == ">" || $keyword == "<") {
				$type = $keywords[$i+1];
				$args[++$typeCount] = $this->mysql_fix_string($args[$typeCount]);
				$types .= $type[count($type)];
				$sql = str_replace($type, "?", $sql);
			}
			else if ($keyword == "from") {
				$isSelect = false;
			}
			else if ($isSelect) {
				$selectList[count($selectList)] = $keywords[$i];
			}
			else if ($keyword =="select") {
				$isSelect = true;
			}
		}
		
		$stmt = mysqli_stmt_init($this->link);
		if (mysqli_stmt_prepare($stmt,$sql)) {
			$this->_list = $selectList;
			$this->_types = $types;
			return $stmt;
		}
		else {
			return null;
		}
	}
	
	private function sql_get_insert_stmt($args)
	{
		$keywords = preg_split("/[\s,()]+/",$args[0]);
		$count = count($keywords);
		$types = ""; //string of param types
		$typeCount = 0;
		$sql = $args[0]; //sanitized result string
		$isValues = false;
		
		for ($i=0; $i < $count; $i++) {
			$keyword = $keywords[$i]; 
			if ($isValues && $keyword != null) {
				$args[++$typeCount] = $this->mysql_fix_string($args[$typeCount]);
				$types .= $keyword[count($keyword)];
				$sql = str_replace($keyword, "?", $sql);
			}
			else if ($keyword =="values") {
				$isValues = true;
			}
		}
		
		$stmt = mysqli_stmt_init($this->link);
		if (mysqli_stmt_prepare($stmt,$sql)) {
			$this->_types = $types;
			return $stmt;
		}
		else {
			return null;
		}
	}
	
	private function internal_select($args)
	{
		//start with generic prepare
		$stmt = $this->sql_get_select_stmt($args);
		$selectList = $this->_list;
		$types = $this->_types;
		$result = null;
		$return = array();
		$selectCount = count($selectList);
		$bindResult = '$stmt';
		for ($i=0; $i < $selectCount; $i++) { 
			$bindResult .= sprintf(',$result[\'%s\']',$selectList[$i]);
		}
		$bindParams = '$stmt,$types';
		$length = strlen($types);
		for ($i=0; $i < $length; $i++) {
			$type = $types[$i];
			$arg = $args[$i+1];
			if ($type == "i" && is_numeric($arg)) {
				
			}
			else if ($type == "d" && is_double($arg)) {
				
			}
			else if ($type == "s" && is_string($arg)) {
				
			}
			else {
				return false;
			}
			$bindParams .= sprintf(',$args[%d]',$i+1);
		}
		eval("mysqli_stmt_bind_param($bindParams);");
		mysqli_stmt_execute($stmt);
		eval("mysqli_stmt_bind_result($bindResult);");
		$count = 0;
		$fieldCount = $stmt->field_count;
		while (mysqli_stmt_fetch($stmt)) {
			foreach ($result as $key => $value) {
				$return[$count][$key] = $value;
			}
			$count++;
		}
		mysqli_stmt_close($stmt);
		return $return;
	}
	
	private function internal_insert($args)
	{
		//start with generic prepare
		$stmt = $this->sql_get_insert_stmt($args);
		
		$insertList = $this->_list;
		$types = $this->_types;
		$result = null;
		$insertCount = count($insertList);
		$bindParams = '$stmt,$types';
		$length = strlen($types);
		
		for ($i=0; $i < $length; $i++) {
			$type = $types[$i];
			$arg = $args[$i+1];
			if ($type == "i" && is_numeric($arg)) {
				$args[$i+1] = intval($arg);
			}
			else if ($type ==  "d" && is_double($arg)) {
				$args[$i+1] = doubleval($arg);
			}
			else if ($type == "s" && is_string($arg)) {
				$args[$i+1] = strval($arg);
			}
			else {
				//sql injection!
				return false;
			}
			$bindParams .= sprintf(',$args[%d]',$i+1);
		}

		eval("mysqli_stmt_bind_param($bindParams);");
				
		mysqli_stmt_execute($stmt);
		$id = $stmt->insert_id;
		
		mysqli_stmt_close($stmt);
		return $id;
	}

	public function sql_select($sql)
	{
		return $this->internal_select(func_get_args());
	}
	
	
	public function sql_insert($sql)
	{
		return $this->internal_insert(func_get_args());
	}
}

$db = new Data($link);
print_r($db->sql_select("select userId, name from user where userId > %i order by name",0));
// print_r($db->sql_insert("insert into user (password,name) values (%i,%s)",'6','third'));
?>